package main;

//TCPClient.java

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

import message.Message;

import com.chaosinmotion.asn1.BerInputStream;
import com.chaosinmotion.asn1.BerOutputStream;

public class Client {
	private InputStream input;
	private OutputStream output;

	public Client() {
		String toServer;
		try {
			Socket clientSocket = new Socket("localhost", 5000);
			BufferedReader inFromUser = new BufferedReader(
					new InputStreamReader(System.in));
			output = clientSocket.getOutputStream();
			input = clientSocket.getInputStream();

			while (true) {
				System.out.print("Please input an integer: ");
				toServer = inFromUser.readLine();
				int num = 0;
				try {
					if (toServer.equals("q"))
						break;
					num = Integer.parseInt(toServer);
				} catch (NumberFormatException e) {
					continue;
				}

				// send a number to the server
				Message msg = new Message();
				msg.num.setValue(num);
				msg.str.setValue("".getBytes());
				sendMessage(msg);

				msg = receiveMessage();
				String converted = convert(new String(msg.str.getValue()));
				msg.str.setValue(converted.getBytes());
				sendMessage(msg);

				Message result = receiveMessage();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String argv[]) throws Exception {
		new Client();
	}

	public Message receiveMessage() throws IOException {
		BerInputStream in = new BerInputStream(input);
		Message msg = new Message();
		msg.decode(in);
		System.out.println("Server -> Client: " + msg.num.getValue() + " "
				+ new String(msg.str.getValue()));
		return msg;
	}

	public void sendMessage(Message msg) {
		System.out.println("Client -> Server: " + msg.num.getValue() + " "
				+ new String(msg.str.getValue()));
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		BerOutputStream out = new BerOutputStream(baos);
		try {
			msg.encode(out);
			printHex(baos.toByteArray());
			output.write(baos.toByteArray());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static String convert(String append) {
		char[] chars = append.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (chars[i] >= 'a' && chars[i] <= 'z')
				chars[i] -= 32;
			else if (chars[i] >= 'A' && chars[i] <= 'Z')
				chars[i] += 32;
		}
		return new String(chars);
	}

	public void printHex(byte[] coded) {
		System.out.print("\tto byte array in HEX : ");
		String hexDigits = "0123456789ABCDEF";
		for (int i = 0; i < coded.length; i++) {
			int c = coded[i];
			if (c < 0)
				c += 256;
			int hex1 = c & 0xF;
			int hex2 = c >> 4;
			System.out.print(hexDigits.substring(hex2, hex2 + 1));
			System.out.print(hexDigits.substring(hex1, hex1 + 1) + " ");
		}
		System.out.println();
	}
}
